package mspbots.cw.client.core.data.subdata;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.cw.client.core.AbstractToolsUtil;
import mspbots.cw.client.core.data.BaseSyncService;
import mspbots.cw.client.core.client.ClientProperties;
import mspbots.cw.common.QueryParams;
import mspbots.cw.common.RabbitKeys;
import mspbots.cw.common.ResultMsg;
import mspbots.cw.common.ResultSync;
import mspbots.cw.common.subdata.SubDataType;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.UUID;

/**
 * mspbots.data.cw.core.invoices.OrdersSubServiceImpl
 *
 * @author <a href="https://github.com/vnobo">Alex bob</a>
 * @date Created by 2020/9/8
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class OrdersStatusesServiceImpl extends AbstractToolsUtil implements BaseSyncService {


    private Mono<Void> syncOrderStatuses(ClientProperties properties) {
        ResultSync resultSync = ResultSync.withDefault("ORDERS-STATUSES-SYNC");
        return this.getOrderStatuses(properties)
                .contextWrite(ctx -> ctx.put("resultSync", resultSync))
                .doOnNext(resultNode -> this.sendEntity(RabbitKeys.SUB_DATA_SYNC_QUEUE_KEY, ResultMsg.builder()
                        .requestId(UUID.randomUUID()).id(resultNode.get("id").longValue())
                        .action(SubDataType.ORDERS_STATUSES.name()).entity(resultNode)
                        .tenantId(properties.getTenantId())
                        .syncDate(LocalDateTime.now()).build()))
                .then();
    }

    private Flux<JsonNode> getOrderStatuses(ClientProperties properties) {
        return this.cwWebClient.fetch("/sales/orders/statuses", QueryParams.withDefault())
                .contextWrite(ctx -> ctx.put("properties", properties));
    }

    private Mono<Void> syncBillingTerms(ClientProperties properties) {
        ResultSync resultSync = ResultSync.withDefault("BILLING-TERMS-SYNC");
        return this.getBillingTerms(properties)
                .contextWrite(ctx -> ctx.put("resultSync", resultSync))
                .doOnNext(resultNode -> this.sendEntity(RabbitKeys.SUB_DATA_SYNC_QUEUE_KEY, ResultMsg.builder()
                        .requestId(UUID.randomUUID()).id(resultNode.get("id").longValue())
                        .action(SubDataType.BILLING_TERMS.name()).entity(resultNode)
                        .tenantId(properties.getTenantId())
                        .syncDate(LocalDateTime.now()).build()))
                .then();
    }

    private Flux<JsonNode> getBillingTerms(ClientProperties properties) {
        return this.cwWebClient.fetch("/finance/billingTerms", QueryParams.withDefault())
                .contextWrite(ctx -> ctx.put("properties", properties));
    }

    @Override
    public Mono<Void> syncSlow(ClientProperties properties) {
        return Flux.concatDelayError(this.syncBillingTerms(properties),
                this.syncOrderStatuses(properties))
                .then();
    }
}
